/*
 * Copyright 2009 Douglas Lockamy, dlockamy_at_gmail.com
 * All rights reserved. Distributed under the terms of the MIT License.
 */

if (!this.benix) benix = new kernel();

debug=0;

function kernel(args)
{


    this.version = '0.1';

    this.user;
    this.password;
    this.currentDir = '/';
    this.rootPath;
    this.stdoutBuffer = '';

    this.stdoutReg;
    this.stdinReg;

    this.KeyUpReg;

    this.mouseMoveReg;
    this.mouseDownReg;
    this.mouseUpReg;

    this.onSelectReg;

    this.tickReg;
    this.browser;

//this.init = function()
//{
        this.IE = false;
        this.Firefox = false;
        this.Safari = false;
        this.version = null;

        agent = navigator.userAgent;
        s = "MSIE";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.IE = true;
            //this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='IE';
            alert('We\'re Sorry, IE is not capable of displaying this content. Consider Firefox or Safari for your browsing needs');
            return;
        }

        s = "WebKit";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.SAFARI = true;
            this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='Safari';
            return;
        }
        s = "Firefox";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.FIREFOX = true;
            this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='Firefox';
            return;
        }
        s = "Chrome";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.CHROME = true;
            this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='Chrome';      
            return;
        }

    ajaxObj = new this.ajaxBuilder();

    stdoutReg = new Array();
    stdinReg = new Array(); 

    KeyUpReg = new Array();
    
    mouseMoveReg = new Array();
    mouseDownReg = new Array();
    mouseUpReg = new Array();
    
    onSelectReg = new Array();
    
    tickReg =  new Array();   

    vfs_init();
    
    document.onmousedown = this.MouseDown;
    document.onmouseup = this.MouseUp;
    document.onmousemove = this.MouseMove;
    document.onkeydown = this.stdin;
    document.onkeyup = this.KeyUp;
    
    document.onselect = this.OnSelect;
 
    vfs_mount(null,'wmfs','/local/window',null,null,null);

    vfs_write('/dev/window',4,'/local/window',null,null,null);
    vfs_write('/dev/window',4,'/remote/0/dev/window',null,null,null);
        
    tick('start');

    procLoop();
 
    stdout('Start benix for ' + this.browser + '<br>');    
    //login.main();
//};

    browser = function() 
    {
        this.IE = false;
        this.Firefox = false;
        this.Safari = false;
        this.version = null;

        agent = navigator.userAgent;
        s = "MSIE";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.IE = true;
            //this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='IE';
            alert('We\'re Sorry, IE is not capable of displaying this content. Consider Firefox or Safari for your browsing needs');
            return;
        }

        s = "WebKit";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.SAFARI = true;
            this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='Safari';
            return;
        }
        s = "Firefox";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.FIREFOX = true;
            this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='Firefox';
            return;
        }
        s = "Chrome";
        if ((i = agent.indexOf(s)) >= 0)
        {
            this.CHROME = true;
            this.browserVersion = parseFloat(agent.substr(i + s.length) );
            this.browser='Chrome';      
            return;
        }
    };

ajaxObj;

this.ajaxBuilder = function()
{
//based on wikipedia's demo emplimentation
    try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e){
        try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e){
            try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e){
                try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e){
                    try { return new XMLHttpRequest() } catch(e){
                        throw new Error( "This browser does not support XMLHttpRequest." );
                    }
                }
            }
        }
    }
};

this.wget = function(url)
{
    //if( 
    wget_ajaxObj = new this.ajaxBuilder();
    wget_ajaxObj.open("GET",url,false);
    //{
        wget_ajaxObj.send(null);
        alert(wget_ajaxObj.responseText);
        return(wget_ajaxObj.responseText); 
    //}
    //else
        return -1;
};

this.wput = function(url,file)
{
    //if( 
    this.ajaxObj.open("PUT",url,false);
    //{
        this.ajaxObj.send(null);
        return(this.ajaxObj.responseText); 
    //}
    //else
        return -1;

    return 0;
};

this.registerOnSelect = function( stdinObj )
{
    this.onSelectReg[length] = stdinObj;
};

this.registerMouseDown = function( stdinObj )
{
    this.mouseDownReg[length] = stdinObj;
};

this.registerMouseUp = function( stdinObj )
{
    this.mouseUpReg[length] = stdinObj;
};

this.registerMouseMove = function( stdinObj )
{
    this.mouseMoveReg[length] = stdinObj;
};

this.OnSelect = function(event)
{
    count = 0;

    while(count <= this.onSelectReg.length-1)
    {
        this.mouseUpReg[count].onSelect(event);
        count++;
    };
};

this.MouseDown = function(event)
{
    count = 0;

    while(count <= this.mouseDownReg.length-1)
    {
        this.mouseUpReg[count].mouseDown(event);
        count++;
    };
};

this.MouseUp = function(event)
{
    count = 0;

    while(count <= this.mouseUpReg.length-1)
    {
        this.mouseUpReg[count].mouseUp(event);
        count++;
    };
};

this.MouseMove = function(event)
{
    count = 0;
    
    while(count <= this.mouseMoveReg.length-1)
    {
        this.mouseUpReg[count].mouseMove(event);
        count++;
    };
};  

this.debug = function(formatedString)
{
    if(debug)
        this.stdout(formatedString);
};

this.stdout = function( formatedString )
{
    if(this.stdoutBuffer.length < 80 )
    {
        this.stdoutBuffer = this.stdoutBuffer + formatedString;
        document.getElementById('content').innerHTML = this.stdoutBuffer;
    }
    else
    {
        this.stdoutBuffer = formatedString;
        document.getElementById('content').innerHTML = this.stdoutBuffer;    
    }
};

keyCodeMapper= function(event)
{
    //alert(event.keyCode);
    
    //we should be mapping against an array of key codes and characters
    /*
    return(keyArray[event.keyCode] );
    */
        if(event.keyCode >= 48 && event.keyCode <= 57 )
    {
        currChar = String.fromCharCode(event.keyCode);
        
        if(event.shiftKey)
             bash.buffer += currChar;       
        else
            currChar = currChar.toLowerCase(); 
            //alert(currChar);    
    }
    
    else if(event.keyCode >= 65 && event.keyCode <=90 )
    {
        currChar = String.fromCharCode(event.keyCode);
        
        if(event.shiftKey)
             bash.buffer += currChar;       
        else
            currChar = currChar.toLowerCase();     
    }
    else if(event.keyCode >= 48 && event.keyCode <=55 )
        currChar = parseInt( String.fromCharCode(event.keyCode) );

    else if(event.keyCode >= 96 && event.keyCode <=105 )
        currChar = parseInt( String.fromCharCode(event.keyCode) );

    else if(event.keyCode==13)
    {   
        currChar = "\\n";  
    }

    else if(event.keyCode==191)
       currChar= '/'; 
 
    else if(event.keyCode==8)
        currChar = '\\bck';
 
    else if(event.keyCode == 186)
    {        
        //if(event.shiftKey)
            currChar = ':';       
        //else
         //   currChar = ';';   
    }  
    
    else if(event.keyCode == 191)
    {
        currChar = '/'; 
    }

    else if(event.keyCode == 190)
    {
        currChar = '.'; 
    }
 
    else if(event.keyCode == 32)
    {
        currChar = ' '; 
    }
     else if(event.keyCode == 16)
    {
        return;
    }
     else if(event.keyCode == 192)
    {
        currChar = '*';
    }
    
    return currChar;
};

this.stdin = function(event)
{
    count = 0;

    if(event.keyCode == 16)
    {
        return;
    }
    else
        var currChar = keyCodeMapper(event);

    if(this.username && this.password)
    {
        while(count <= this.stdinReg.length-1)
        {
            this.stdinReg[count].keydown(currChar);
            count++;
        };
    }
    else
        login.input(currChar);
};

this.registerStdin = function( stdinObj )
{
    this.stdinReg[length ] = stdinObj;
};

this.keyUp = function(event)
{
    count = 0;

    if(this.username && this.password)
    {
        while(count <= this.KeyUpReg.length-1)
        {
            this.KeyUpReg[count].keydown(event);
            count++;
        };
    }
    else
        login.input(event);
};

this.registerKeyUp = function( stdinObj )
{
    this.KeyUpReg[length ] = stdinObj;
};

this.flush = function(arg)
{
    if(arg == 'stdout')
    {
        this.stdoutBuffer = "";
        content.innerHTML = this.stdoutBuffer;
    }
}

this.registerTick = function( arg )
{
    this.tickReg[length ] = arg;
};

this.tick = function(arg)
{
    count = 0;

    while(count <= this.tickReg.length-1)
    {
        this.tickReg[count].tick(arg);
        count++;
    };
    
    setTimeout(this.tick,20);
    
};

this.read = function(path,flags,buffer,offset,length,sessionKey)
{
    //if(!sessionKey)
      //  return -1;
    //else
        return(vfs.read(path,flags,buffer,offset,length,sessionKey) ); 
};

this.write = function(path,flags,buffer,offset,length,sessionKey)
{
    //if(!sessionKey)
    //    return -1;
    //else
        return(vfs.write(path,flags,buffer,offset,length,sessionKey));
};

this.procList=0;

this.procInit = function()
{
    this.procList = new Array();
};

this.procExec = function(procClass,flags)
{
    this.procList[this.procList.length ] = procClass;
    procClass.init(flags);
};

this.procLoop = function()
{
    count = 0;
    while(count < this.procList.length)
    {
        this.procList[count].isRunning=true;
        this.procList[count].Run();
        this.procList[count].isRunning=false;
        count++;
    };
    
    setTimeout(this.procLoop,20);
};

this.procEndTask = function(procClassName)
{

};

this.fsMakeNode = function(rootNode,path)
{

};

this.fsRemoveNode = function(rootNode,path)
{

};

this.fsCopy = function(sourcePath,destPath,flags)
{
    this.stdout("copy"+sourcePath+"to"+destPath+"<br>");
    if(sourcePath[sourcePath.length-1]=="*" && flags=="0r")
    {
        var cleanCount = 1;
        var cleanPath = "";
        var splitPath =  sourcePath.split("/"); 
        while(cleanCount < splitPath.length-1 )
        {
            cleanPath = cleanPath+"/"+splitPath[cleanCount];                
            cleanCount++;
        };
               
        readNode =  this.read(cleanPath,2,null,null,null,'vfs.sessionKey');
        var count = 0;

        if(readNode == "-1")
        {
            alert("error");
            return -1;
        }

        else if(readNode.Data.length > 0 && readNode.Type == 1)
        {
            while(count < readNode.Data.length)
            {
                    currNode = readNode.Data[count];
                    this.fsCopy(cleanPath+"/"+currNode.Name,destPath+"/"+currNode.Name,flags);
                    count++;             
            }
        }
    }      
      
    else if(this.read(sourcePath,CHECKDIR,null,null,'vfs.sessionKey') && flags=="0r")
    {
        this.write(destPath,CREATEDIR,1,null,null,'vfs.sessionKey');
             
        readNode =  this.read(sourcePath,2,null,null,null,'vfs.sessionKey');
        var count = 0;

        if(readNode == "-1")
        {
            alert("error2");
            return -1;
        }

        else if(readNode.Data.length > 0 && readNode.Type == 1)
        {
            while(count < readNode.Data.length)
            {
                    currNode = readNode.Data[count];
                    this.fsCopy(sourcePath+"/"+currNode.Name,destPath+"/"+currNode.Name,flags);
                    count++;             
            }
        }
    }
    else if(vfs.read(sourcePath,CHECKDIR,null,null,null) && flags!="-r")
    {
       return -1 
    }
    else
    {
        buffer = vfs.read(sourcePath,GETFILEDATA,null,null,null);
        return(vfs.write(destPath,CREATEDATAFILE,buffer,null,null,null) );
    };

    return -1;
};

this.fsWalk = function(startNode,path)
{
    if(path.length==1 && path.charAt(0) == '/')
    {
        return startNode;
    }

    if(path.charAt(0) != '/')
    {
        return -1;
    }
    
    var nodeArray = path.split("/");
   
    aNode = startNode.Data[0];
        
    depth = 1;
    
    while(aNode && aNode.Name != nodeArray[nodeArray.length-1] && depth <= nodeArray.length)
    {
       while(aNode.Name != nodeArray[depth] && depth <= nodeArray.length )
        {      
                if(aNode.next != 0)
                {
                    aNode = aNode.next;
                }
                else
                {
                    return -1;
                }
        };    
        if(aNode.Name != nodeArray[nodeArray.length-1] && aNode.Type != 5 && aNode.Type != 6)
        {
            aNode=aNode.Data[0];
            depth++;
        }   
        
        if(aNode && aNode.Name == nodeArray[nodeArray.length-1] && depth < nodeArray.length-1)
        {
            znode = 0;
            while(aNode.Data[znode].Name != nodeArray[depth+1] && depth <= nodeArray.length )
            {   
                if(aNode.Data[znode].next!=0)
                    znode++;
                else
                    return -1;
            }; 
            if(aNode.Data[znode].Name == nodeArray[depth+1])
            {
                depth++;
                aNode=aNode.Data[znode];
            }
            else
                return -1;
        } 

        if(aNode && aNode.Type == 5 )
        {
            if(aNode.Name == nodeArray[depth])
                return(aNode);
            else
                return -1;
        }; 
        if(aNode && aNode.Type == 4 )
        {
            if(aNode.Name == nodeArray[depth])
                return(aNode);
            else
                return -1;
        }; 
        if(aNode && aNode.Type == 6 )
        {
            if(aNode.Name == nodeArray[depth])
                return(aNode);
            else
                return -1;
        };
     
        if(!aNode)
            return -1;
    };
        return aNode;
};

this.fsBuildMountPath = function(mNode,mountPath)
{
     var name = mountPath.split("/");
     var path = '';
     var i = 1;
     
     while(i < name.length-1)
     {
        path += '/' + name[i];
        i++;
     }
       
    return path;
};

this.parsePath = function(mNode,loadPath)
{
    var mPath = '';
    var counter = 0;
    
    var pathArray = loadPath.split('/');
    
    while(pathArray[counter] != mNode.Name && counter < pathArray.length)
    {
        counter++;
    }
    
    //skip the mount point's name
    counter++;
    
    while( counter < pathArray.length)
    {
        mPath = mPath + "/" + pathArray[counter];
        counter++;
    }
    if(mPath)   
        return mPath;
    else
        return('/');
};

    var vfsList = new Array();
    fsList = new Array();
    var rootfs;
    
    function jsInclude(jsFile)
    {
        eval(wget(jsFile) );
    };

    function vfsNode() {
        vfsNode.Name = "";
        vfsNode.item = 0;
        vfsNode.Parent = 0;
    };

    var rootfs;

    vfs_init = function()
    {

        rootfs = new fileNode();
        rootfs.Name="/";
        rootfs.Type = 1;
        rootfs.prev = 0;
        rootfs.next = 0;
        rootfs.Data = new Array();
        rootfs.Parent = 0;
    
        rootfs.Data = new Array();
        rootfs.Data[0] = new fileNode();

        vfs_write('/local',1,1);
        vfs_write('/remote',1,1);
        vfs_write('/home',1,1);    
        vfs_write('/dev',1,1);    
        vfs_write('/var',1,1);
    };

    vfs_mount = function(serverAddress,fs_type,mountPoint,user,pass,argv)
    {
        var mPath = this.fsBuildMountPath(rootfs,mountPoint);
        var name = mountPoint.split("/");
        var aNode = vfs.walk(mPath);
        var counter = 0;

        while(vfsList[counter].Name != fs_type && counter < vfsList.length-1)
        {  
            counter++;
        }
        if(aNode.Type == 1 && vfsList[counter].Name == fs_type)
        {
            aNode.Data[aNode.Data.length] = new fileNode(); 

            var mounter = aNode.Data[aNode.Data.length - 1 ];

            if(aNode.Data.length > 1)
                aNode.Data[aNode.Data.length-2].next = mounter;
        
            var aNumber = aNode.Data.length - 1;
        
            mounter.Name=name[name.length-1];
            mounter.Type = 5;
            mounter.Data= new mountNode();
            mounter.Data[0]=fs_type;
            mounter.Data[1]=serverAddress;
            mounter.Data[2]=0;
            mounter.Data[3]=vfsList[counter].item;
            mounter.Parent = aNode;

            if(aNode.Data.length < 1)
                mounter.prev=0;
            else
                mounter.prev=aNode.Data[aNode.Data.length-2];
            
            mounter.next=0;

            return(vfsList[counter].item.mount(serverAddress,fs_type,mountPoint,user,pass,argv) );
        }
        else
            return -1;
    };

    vfs_umount = function(mountPoint)
    {
        var aNode = vfs_walk(mountPoint);
        if(aNode.Type == 5)
        {
            if(!aNode.Data[3].umount() )
            {
                vfs_write(mountPoint,0,null);
            }
            return 0;
        }
        else  
            this.stdout('<br>Not a mount point<br>');
    };

    vfs_read = function(path,flags,buffer,offset,length,sessionKey)
    {

        if(flags =='1')
        {
            var readNode = vfs_walk(path);
        
            if(readNode.Type == 1)
                return 1;
            if(readNode.Type==4)
            {
                return(vfs_read(readNode.Data,1,null,null,null,sessionKey) );
            } 
            if(readNode.Type==5)
            {
                var loadPath = parsePath(readNode,path);
                if(loadPath == '/')
                    return 1;
                else
                    return(readNode.Data[3].read(loadPath,flags,buffer,offset,length,sessionKey) );
            }  
            if(readNode.Type==6)
            {
                var loadPath = parsePath(readNode,path);
                return(vfs_read(readNode.Data[0]+loadPath,flags,buffer,offset,length,sessionKey) );
            } 
            else
                return 0;
        }
        if(flags =='2')
        {    
            var readNode = vfs_walk(path);
        
            if(readNode.Type == 1)
                return readNode;
            if(readNode.Type==4)
            {
                var loadPath = this.parsePath(aNode,path);
                return(vfs.read(readNode.Data+loadPath,2,buffer,offset,length,sessionKey) );
            } 
            if(readNode.Type==5)
            {
                var loadPath = this.parsePath(aNode,path);
                return(readNode.Data[3].read(loadPath,flags,buffer,offset,length,sessionKey) );
            }    
            if(readNode.Type==6)
            {
                var loadPath = this.parsePath(readNode,path);
                return(vfs.read(readNode.Data[0]+loadPath,2,buffer,offset,length,sessionKey) );
            } 
            else
                return readNode;
        }
        if(flags == '3' || flags == '4' )
        {  
            var readNode = vfs_walk(path);
        
            if(readNode.Type == 1)
            {
            if(readNode.Data[0].Name)
            return readNode.Data[0].Name;
            else
            return "File Read Error"
            }
            if(readNode.Type==4)
            {
                var loadPath = this.parsePath(readNode,path);        
                return(vfs.read(readNode.Data+loadPath,flags,buffer,offset,length,sessionKey) );
            } 
            if(readNode.Type==5)
            {
                var loadPath = this.parsePath(readNode,path);        
                return(readNode.Data[3].read(loadPath,flags,buffer,offset,length,sessionKey) );
            } 
            if(readNode.Type==6)
            {
                var loadPath = this.parsePath(readNode,path);
                return(vfs.read(readNode.Data[0]+loadPath,2,buffer,offset,length,sessionKey) );
            } 
            else
                return readNode.Data;    
        }
        else
            return -1;
    };

    vfs_write = function(path,flags,buffer,offset,length,sessionKey)
    {
    
        var workPath = '/';
        var aNode = 0;
        var pathArray = path.split('/');
        var counter=0;
    
        while(counter <= pathArray.length-2)
        {
            if(workPath == '/')
                workPath = workPath + pathArray[counter];
            else
                workPath = workPath + '/' + pathArray[counter];
            counter++;
        }

        if(flags==0)
        {
        //unlink a node
            counter = 0;
            aNode = vfs.walk(path);
            
            if(aNode.Type == 5)
            {
                var loadPath = this.parsePath(aNode,path);
                return(aNode.Data[3].write(loadPath,flags,buffer,offset,length,sessionKey) );
            };
            if(aNode.Type == 4)
            {
                fileStruct = path.split('/');
                remPath = aNode.Data+"/"+fileStruct[fileStruct.length-1];
                return(vfs.write(remPath,flags,buffer,offset,length,sessionKey) );
            };
            if(aNode.Type == 6)
            {
                fileStruct = path.split('/');              
                var counter = 0;
                alert("remove dir from union mount "+aNode.Data.length );
                while(counter < aNode.Data.length)
                {
                    remPath = aNode.Data[counter]+"/"+fileStruct[fileStruct.length-1];
                    vfs.write(remPath,flags,buffer,offset,length,sessionKey)
                    counter++;
                };
                return 0;
            };
            var prevNode = aNode.prev;   
            var nextNode = aNode.next;      

            while(aNode.Parent.Data[counter].Name != aNode.Name && counter < aNode.Parent.Data.length)
            {
                counter++;
            }
            
            aNode.Parent.Data.splice(counter,1);
            
            prevNode.next = nextNode;
            nextNode.prev = prevNode;
    }
    
    if(flags==1)
    {

//        if(vfs.walk(path) != -1)
  //          return -1;
    
        aNode = vfs.walk(workPath);
        if(aNode.Type == 1 && buffer == 1 )
        {
            aNode.Data[aNode.Data.length] = new fileNode;
            var newDir = aNode.Data[aNode.Data.length-1];
            newDir.Name = pathArray[pathArray.length-1];
            newDir.Type = 1;
            newDir.next = 0;
            newDir.Data = new Array();
            newDir.prev = aNode.Data[aNode.Data.length-1];
            newDir.Parent = aNode;

            if(aNode.Data.length >= 2 )
            {        
                aNode.Data[aNode.Data.length-2].next=newDir;
            }   
            return 0;       
        }
        else if(aNode.Type==4)
        { 
            return(vfs.write(aNode.Data+"/"+pathArray[pathArray.length-1],flags,buffer,offset,length,sessionKey) );
        }
        
        else if(aNode.Type==5 )
        {
            var loadPath = this.parsePath(aNode,path);

            return(aNode.Data[3].write(loadPath,flags,buffer,offset,length,sessionKey) );
        }    
        else if(aNode.Type==6)
        {
            var loadPath = this.parsePath(aNode,path);
            var count = 0;
            while(count < aNode.Data.length)
            {
                vfs.write(aNode.Data[count]+loadPath,flags,buffer,offset,length,sessionKey);
                count++;
            }
            return( 0  );
        }  
        else
            return -1;
            
    }
    else if(flags==2)
    {
       // if(vfs.walk(path) != -1)
         //   return -1;
        aNode = vfs.walk(workPath);

        if(aNode.Type==1 )
        {
            var newfile = aNode.Data[aNode.Data.length] = new fileNode();
            newfile.Name = pathArray[pathArray.length-1];
            newfile.Type = 2;
            newfile.next = 0;
            newfile.Data = buffer;
            newfile.prev = aNode.Data[aNode.Data.length-1];
            
            if(aNode.Data.length >= 2 )
            {        
                aNode.Data[aNode.Data.length-2].next=newfile;
            }           
        }
        
        if(aNode.Type==5 )
        {
            var loadPath = this.parsePath(aNode,path);

            return(aNode.Data[3].write(loadPath,flags,buffer,offset,length,sessionKey) );
        }  
        
        if(aNode.Type == 6 )
        {
            var loadPath = this.parsePath(aNode,path);

            var counter = 0;

            while(counter < aNode.Data.length)
            {
                vfs.write(aNode.Data[counter]+loadPath,flags,buffer,offset,length,sessionKey);
                counter++;
            }
            
            return 0;
        } 
        
        else
            return -1;
    }
    else if(flags==3)
    {
        aNode = vfs_walk(workPath);
 //      if(vfs.walk(buffer))
            var bNode = vfs.walk(buffer);
   //     else 
     //       return -1;
       if(bNode.Type == 1 || bNode.Type == 5)
        {
            if(aNode.Type == 1 )
            {
                aNode.Data[aNode.Data.length] = new fileNode;
                var newDir = aNode.Data[aNode.Data.length-1];
                newDir.Name = pathArray[pathArray.length-1];
                newDir.Type = 4;
                newDir.next = 0;
                newDir.Data = buffer;
                newDir.prev = aNode.Data[aNode.Data.length-1];
                newDir.Parent = aNode;

                if(aNode.Data.length >= 2 )
                {        
                    aNode.Data[aNode.Data.length-2].next=newDir;
                } 
                return 0;         
            }
        
            else if(aNode.Type==5 )
            {
                var loadPath = this.parsePath(aNode,path);
                return(aNode.Data[3].write(loadPath,flags,buffer,offset,length,sessionKey) );
            }  
                
            else
                return -1;
        }
        if(bNode.Type == 5)
        {
            if(aNode.Type==1 )
            {
                var newfile = aNode.Data[aNode.Data.length] = new fileNode();
                newfile.Name = pathArray[pathArray.length-1];
                newfile.Type = 4;
                newfile.next = 0;
                newfile.Data = buffer;
                newfile.prev = aNode.Data[aNode.Data.length-1];
            
                if(aNode.Data.length >= 2 )
                {        
                    aNode.Data[aNode.Data.length-2].next=newfile;
                }           
            }
        
            if(aNode.Type==5 )
            {
                var loadPath = this.parsePath(aNode,path);
                return(aNode.Data[3].write(loadPath,flags,buffer,offset,length,sessionKey) );
            }  
        
            else
                return -1;       
        }   

        else 
            return bNode.Type;
    }
    else if(flags==4)
    {
        //create a union link//
        //but only supported under /dev
        if(vfs.walk(path)==-1)
        {
            aNode = vfs.walk(workPath);

            if(aNode.Name != "dev")
                return -1;

            if(aNode.Type==1 )
            {
                aNode.Data[aNode.Data.length] = new fileNode;
                var newDir = aNode.Data[aNode.Data.length-1];
                newDir.Name = pathArray[pathArray.length-1];
                newDir.Type = 6;
                newDir.next = 0;
                newDir.Data = new Array();
                newDir.prev = aNode.Data[aNode.Data.length-1];
                newDir.Parent = aNode;

                if(aNode.Data.length >= 2 )
                {        
                    aNode.Data[aNode.Data.length-2].next=newDir;
                }   
                newDir.Data[newDir.Data.length] = buffer;          
            }
        
            if(aNode.Type==5 )
            {
                var loadPath = this.parsePath(aNode,path);
                return(aNode.Data[3].write(loadPath,flags,buffer,offset,length,sessionKey) );
            }  
        
            else
                return -1;
        }
        else 
        {
            aNode = vfs_walk(workPath);

            if(aNode.Name != "dev")
                return -1;
                
            aNode = vfs_walk(path);

            aNode.Data[aNode.Data.length] = buffer;          

            return 0;
        }
    } 
    
    else if(flags==5)
    {
        if(vfs_walk(path) )
        {
            aNode = vfs_walk(path);

            if(aNode.Type == 5)
            {
                return -1;
            }
            if(aNode.Type == 6)
            {
                aNode.Data[aNode.Data.length] = buffer;
                return 0;
            }
            else
                aNode.Data = buffer;
        }
        else
            return -1;
    }
    
    else 
        return -1;

};

    vfs_stat = function(path)
    {
        var aNode = vfs_walk(path);
        this.stdout(aNode.Type + '<br>');
        this.stdout(aNode.Data.length+ '<br>' );
    };

};
